iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0

https://ithelp.ithome.com.tw/upload/images/20260904/20124384E8ILORcPug.jpg

今天介紹什麼工具

  1. Hooks(勾子):可以在 Agy CLI 的每個執行階段建立勾子,可以強制要他做某件事,也可以建立程式腳本,例如可以建立一個程式碼格式化的 Hooks 在 PostToolUse 階段,這樣 AI 產完程式碼後會使用 Lint 工具自動格式化程式碼,這樣比較省 Context 和 Token

Agy CLI 的 5 大生命週期事件

Antigravity 的執行迴圈包含以下五個核心事件節點:

  1. PreInvocation(思考前置注入):在模型進行每次思考推論之前觸發,可用於動態注入暫態提示詞(ephemeralMessage)或補充環境資訊。
  2. PreToolUse(工具執行前審查):在代理呼叫具體工具(例如執行指令或修改檔案)前觸發,可用於安全過濾、權限放行或參數覆寫(overwrite)。
  3. PostToolUse(工具執行後處理):在工具執行完成後觸發,為程式碼排版與自動執行 Lint 檢查的最佳時機
  4. PostInvocation(推論後置控制):在本輪推論與工具步驟全部執行完畢時觸發,可用於檢驗產出品質;若需要強制代理繼續修正,可設定 force_continue 進入下一輪迴圈。
  5. Stop(對話串結束前驗收)**:在代理迴圈準備終止並回覆使用者時觸發,若驗收項目(如單元測試或整體靜態檢查)未通過,可回傳 continue 阻止代理提前結束。

生命週期執行流程圖

https://ithelp.ithome.com.tw/upload/images/20260904/20124384RRi2yCqf6i.png


設定檔結構與放置路徑

在 Antigravity 體系中,控制代理行為的掛鉤主要配置於 hooks.json,其支援三種不同層級的路徑:

層級 設定檔路徑 優先順序 適用範圍
專案工作區層級(推薦) <workspace>/.agents/hooks.json 最高 專案專用,隨 Git 簽入與團隊成員共用
全域設定層級 ~/.gemini/config/hooks.json 中等 套用於本機開發環境下的所有專案
外掛模組層級 ~/.gemini/config/plugins/<plugin-name>/hooks/hooks.json 條件加載 封裝為共用外掛發布

程式碼檢查(Lint)工具實作範例

以下示範如何建立「修改檔案後即時檢查」與「對話結束前全專案品管」兩道防線。

1. 配置 hooks.json

在專案根目錄下建立 .agents/hooks.json

{
  "code-linter": {
    "enabled": true,
    "PostToolUse": [
      {
        "matcher": "replace_file_content|write_to_file",
        "hooks": [
          {
            "type": "command",
            "command": "./scripts/run-linter.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "Stop": [
      {
        "type": "command",
        "command": "./scripts/verify-all-lint.sh",
        "timeout": 60
      }
    ]
  }
}

關鍵欄位解析:

  • matcher(工具匹配器):使用正規表示式(Regular Expression)篩選目標工具。指定為 "replace_file_content|write_to_file" 可確保僅在實際修改或新增檔案時觸發,避免檢視檔案(view_file)或查詢時做無效檢查。
  • command(執行命令):指定執行的腳本路徑。相對路徑會以 hooks.json 所在目錄為基準。
  • timeout(逾時限制):命令執行的最長秒數(預設為 30 秒)。

2. 實作單檔檢查腳本:./scripts/run-linter.sh

PostToolUse 事件觸發時,CLI 會透過標準輸入(stdin)傳入本次工具執行的 JSON 資料。腳本可從中解析出被修改的檔案路徑並進行修復:

#!/usr/bin/env bash
set -e

# 從 stdin 讀取 JSON 並提取被修改的檔案路徑 TargetFile
PAYLOAD=$(cat)
TARGET_FILE=$(echo "$PAYLOAD" | jq -r '.toolCall.args.TargetFile // empty')

# 確認檔案存在後執行專案指定的 Lint 工具
if [ -n "$TARGET_FILE" ] && [ -f "$TARGET_FILE" ]; then
  # 以 ESLint 為例:針對變更檔案進行自動格式化與檢查
  npx eslint --fix "$TARGET_FILE" || true
fi

# PostToolUse 必須在標準輸出(stdout)印出空 JSON 物件代表執行完成
echo "{}"

3. 實作結束驗收腳本:./scripts/verify-all-lint.sh

當代理完成工作準備結束對話時,觸發 Stop 掛鉤執行全專案檢驗。如果仍有錯誤,將退回給代理繼續修正:

#!/usr/bin/env bash

# 執行全專案靜態檢查並擷取錯誤輸出
LINT_OUTPUT=$(npx eslint . 2>&1)
LINT_STATUS=$?

if [ $LINT_STATUS -ne 0 ]; then
  # 檢驗未通過:回傳 decision: "continue",阻止代理提早結束並注入錯誤細節
  ESCAPED_REASON=$(echo "$LINT_OUTPUT" | jq -Rs .)
  cat <<EOF
{
  "decision": "continue",
  "reason": "靜態檢查未通過,請修復以下報錯後再結束:\n$ESCAPED_REASON"
}
EOF
  exit 0
fi

# 檢驗通過:允許正常退出
echo '{"decision": "stop"}'

安全信任機制設定(trusted_hooks.json

為防止非信任來源的腳本被惡意背景執行,Antigravity CLI 具備安全防禦限制。任何被引用的外部命令或腳本,需登錄於全域的 trusted_hooks.json 中,否則會被系統靜默阻擋。

  • 檔案絕對路徑~/.gemini/trusted_hooks.json

設定格式:

{
  "/Users/username/Project/my-app": [
    "code-linter:./scripts/run-linter.sh",
    "code-linter:./scripts/verify-all-lint.sh"
  ],
  "*": [
    "code-linter:./scripts/run-linter.sh",
    "code-linter:./scripts/verify-all-lint.sh"
  ]
}

登錄原則:

  1. 格式規範:字串格式為 掛鉤名稱:命令指令(例如 code-linter:./scripts/run-linter.sh)。
  2. 雙重註冊:建議在「工作區目錄絕對路徑」與 "*"(萬用字元(Wildcard)鍵)下同時配置該字串。

上一篇
115/15 - ask_question - 互動問答
系列文
第一次用 Antigravity CLI 做出 Plugin 就上手16
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言